<template>
  <div class="chart">
    <div class="chart"></div>
  </div>
</template>

<script>
import * as echarts from 'echarts'
import ResizeListener from 'element-resize-detector'

export default {
  name: 'MsuiCharts',
  props: {
    extraOption: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      chart: null
    }
  },
  watch: {
    extraOption: {
      deep: true,
      handler() {
        this.updateChartView()
      }
    }
  },
  computed: {
    clickEv() {
      return this.extraOption?.functions?.click
    }
  },
  mounted() {
    this.chart = echarts.init(this.$el.firstChild)
    this.updateChartView()
    window.addEventListener('resize', this.handleWindowResize)
    this.addChartResizeListener()
    if (this.clickEv) {
      this.chart.on('click', this.clickEv)
    }
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.handleWindowResize)
  },
  methods: {
    /**
     * 将业务数据加入到基础样式配置中
     * @returns {Object} 完整的echart配置
     */
    assembleDataToOption() {
      // 这部分的图例formatter取决于UI要求，如果你的项目中不需要，就可以不写formatter
      // 由于echarts版本的迭代，这里的写法也有稍许改变
      return Object.assign({}, this.extraOption)
    },

    /**
     * 对chart元素尺寸进行监听，当发生变化时同步更新echart视图
     */
    addChartResizeListener() {
      const instance = ResizeListener({
        strategy: 'scroll',
        callOnAdd: true
      })

      instance.listenTo(this.$el, () => {
        if (!this.chart) return
        this.chart.resize()
      })
    },

    /**
     * 更新echart视图
     */
    updateChartView() {
      if (!this.chart) return
      const fullOption = this.assembleDataToOption()
      this.chart.setOption(fullOption, true)
    },

    /**
     * 当窗口缩放时，echart动态调整自身大小
     */
    handleWindowResize() {
      if (!this.chart) return
      setTimeout(() => {
        this.chart.resize()
      }, 500)
    }
  }
}
</script>

<style scoped>
.chart {
  width: 100%;
  height: 100%;
  position: relative;
}
</style>
